﻿/*
 * Copyright (C) 2012, Jesus Requejo <jesus.requejo@gmail.com> 
 * Licensed under Microsoft Public License (Ms-PL)
 * http://www.microsoft.com/en-us/openness/licenses.aspx#MPL
*/

namespace LoaderServiceTray {

   using System;
   using Infrastructure;

   internal enum ApplicationsAlreadyLaunched {
      True,
      False,
      Unknown,
      Failure
   }

   internal class ApplicationServices {

      #region Methods dealing with "ApplicationsAlreadyLaunched" request
      internal ApplicationsAlreadyLaunched BootApplicationsAlreadyLaunched() {
         var result = ApplicationsAlreadyLaunched.Unknown;

         try {
            var request = GenerateApplicationsLaunchedRequest();
            string response = ServiceMessenger.SendMessageToServiceAndReturnResponse(request);
            result = ParseApplicationsLaunchedResponse(response);
         }
         catch (Exception) {
            result = ApplicationsAlreadyLaunched.Unknown;
         }
         return result;
      }

      private string GenerateApplicationsLaunchedRequest() {
         var sessionId = ThirdParty.ApplicationLoader.GetActiveSessionId();
         return MagicStrings.StartupApplicationsLaunchedRequestMessage + "_" + sessionId.ToString();
      }

      private ApplicationsAlreadyLaunched ParseApplicationsLaunchedResponse(string response) {
         var affirmative = MagicStrings.StartupApplicationsLaunchedAffirmativeResponseMessage;
         var negative = MagicStrings.StartupApplicationsLaunchedNegativeResponseMessage;
         if (string.Equals(response, affirmative, StringComparison.OrdinalIgnoreCase)) {
            return ApplicationsAlreadyLaunched.True;
         }
         else if (string.Equals(response, negative, StringComparison.OrdinalIgnoreCase)) {
            return ApplicationsAlreadyLaunched.False;
         }
         return ApplicationsAlreadyLaunched.Unknown;
      }

      #endregion

      #region Methods dealing with "LaunchStartupApplications" request
      internal bool LaunchStartupApplications() {
         try {
            var request = GenerateLaunchApplicationsRequest();
            string response = ServiceMessenger.SendMessageToServiceAndReturnResponse(request);
            var success = ParseLaunchApplicationsResponse(response);
            return success;
         }
         catch (UserNotAuthorizedException) {
            throw;
         }
         catch (Exception) {
            return false;
         }
      }

      private string GenerateLaunchApplicationsRequest() {
         var sessionId = ThirdParty.ApplicationLoader.GetActiveSessionId().ToString();
         var currentUser = WindowsUsersUtils.GetCurrentUserName();
         return MagicStrings.StartupLaunchApplicationsRequestMessage + "_" + sessionId + "_" + currentUser;
      }

      private bool ParseLaunchApplicationsResponse(string response) {
         var success = MagicStrings.StartupLaunchApplicationsSuccessResponseMessage;
         var failure = MagicStrings.StartupLaunchApplicationsFailureResponseMessage;
         if (string.Equals(response, success, StringComparison.OrdinalIgnoreCase)) {
            return true;
         }
         else if (string.Equals(response, failure, StringComparison.OrdinalIgnoreCase)) {
            return false;
         }
         if (string.Equals(response, MagicStrings.StartupLaunchApplicationsNotAuthorizedResponseMessage, StringComparison.OrdinalIgnoreCase)) {
            throw new UserNotAuthorizedException("Startup applications are not authorized for the current user");
         }
         return false;
      }
      #endregion

      public void LaunchServiceManager() {

         try {
            var path = RegistryManager.ReadInstallationPath();
            var executable = System.IO.Path.Combine(path, MagicStrings.ServiceManagerExecutable);
            ProcessUtils.RunProcess(executable, "");
         }
         catch (System.ComponentModel.Win32Exception ex) {
            var cancelledByUser = 1223; // http://msdn.microsoft.com/en-us/library/ms681383(v=vs.85).aspx
            if (ex.NativeErrorCode != cancelledByUser) {
               throw;
            }
         }
      }
   }
}
